package cn.accjiyun.pki.controller.tax;

import cn.accjiyun.pki.common.controller.BaseController;
import cn.accjiyun.pki.common.entity.PageModel;
import cn.accjiyun.pki.common.entity.QueryEntity;
import cn.accjiyun.pki.common.utils.*;
import cn.accjiyun.pki.entity.*;
import cn.accjiyun.pki.security.AESUtil;
import cn.accjiyun.pki.security.RSAUtils;
import cn.accjiyun.pki.service.PacketsService;
import cn.accjiyun.pki.service.SystemUserService;
import cn.accjiyun.pki.service.TaxService;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.sql.Timestamp;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by jiyun on 2017/5/18.
 */
@Controller
@RequestMapping("/admin/tax")
public class AdminTaxController extends BaseController {

    private static Logger logger = LoggerFactory.getLogger(AdminTaxController.class);

    private static String addTaxPage = getViewPath("/admin/tax/tax-add");
    private static String taxListPage = getViewPath("/admin/tax/tax-list");
    private static String taxManageListPage = getViewPath("/admin/tax/tax-manage-list");

    @Autowired
    private TaxService taxService;
    @Autowired
    private PacketsService packetsService;
    @Autowired
    private SystemUserService systemUserService;

    /**
     * 执行添加税务订单
     */
    @RequestMapping(value="/addTax", produces = "application/json; charset=utf-8")
    @ResponseBody
    public String addTax(HttpServletRequest request) {
        try {
            String incomeString = request.getParameter("income");
            String typeIdString = request.getParameter("taxTypeId");
//            String taxString = request.getParameter("tax");
            String attachUrl = request.getParameter("attachUrl");
            String content = request.getParameter("content");
            String privateKeyUrl = request.getParameter("privateKeyUrl");
            String privateKeyRealPath = handlePath(request.getServletContext().getRealPath("/")) + privateKeyUrl;
            String password = request.getParameter("password");

            //数据验证
            if (!WebUtils.isValidateRealString(incomeString, typeIdString)
                    || !WebUtils.isNumeric(incomeString, typeIdString)) {
                return getReturnJson(404, "数据输入不合法！", null);
            }
            double income = Double.valueOf(incomeString);
            int typeId = Integer.valueOf(typeIdString);
            double taxMoney = taxService.queryTaxTypeById(typeId).getTaxRate() * income;
            String realAttachUrl = null;
            if (WebUtils.isValidateRealString(attachUrl)) {
                realAttachUrl = request.getSession().getServletContext().getRealPath(attachUrl);
            }
            Packets packets = new Packets();
            packets = packetsService.packedMessage(packets, content, realAttachUrl,
                    privateKeyRealPath, password);
            if (packets == null) return getReturnJson(400, "证书信息错误！", null);
            //删除私钥
            new File(privateKeyRealPath).delete();

            //提取表单信息
            Tax tax = new Tax();
            tax.setIncome(income);
            tax.setTax(taxMoney);
            tax.setStatus((byte) 0);
            tax.setCreateTime(new Timestamp(System.currentTimeMillis()));
            tax.setAttachUrl(attachUrl);
            tax.setSystemUserByUserId(SingletonLoginUtils.getLoginSystemUser(request));
            tax.setTaxTypeByTaxTypeId(taxService.queryTaxTypeById(typeId));

            tax.setPacketsById(packets);

            //保存税务订单
            taxService.createTax(tax);
            packets.setId(tax.getId());
            packetsService.createPackets(packets);
        } catch (Exception e) {
            logger.error("AdminTaxController.addTax()---error", e);
            return getReturnJson(400, "添加失败！", null);
        }
        return getReturnJson(200, "添加成功！", "/admin/tax/initTaxList");
    }

    /**
     * 删除
     */
    @RequestMapping("/delete")
    @ResponseBody
    public String delete(HttpServletRequest request) {
        try {
            String[] taxIdsString = request.getParameter("id").split(",");
            int[] taxIds = new int[taxIdsString.length];
            for (int i = 0; i < taxIdsString.length; i++) {
                taxIds[i] = Integer.valueOf(taxIdsString[i]);
            }
            if (taxIdsString != null && taxIdsString.length > 0) {
                taxService.deleteTaxTypeById(taxIds);
                packetsService.deletePackets(taxIds);
            }
        } catch (Exception e) {
            logger.error("AdminTaxController.delete()--error", e);
            return getReturnJson(400, "删除失败！", null);
        }
        return getReturnJson(200, "删除成功！", "reload");
    }

    /**
     * 分页查询税务订单列表
     */
    @RequestMapping("/getTaxList")
    @ResponseBody
    public String getTaxList(HttpServletRequest request) {
        JsonObject resultJson = new JsonObject();

        SystemUser loginSystemUser = SingletonLoginUtils.getLoginSystemUser(request);
        try {
            String pageNoString = request.getParameter("pageNo");
            if (!WebUtils.isValidateRealString(pageNoString)
                    || !WebUtils.isNumeric(pageNoString)) {
                return getReturnJson(400, "数据输入不合法！", null);
            }
            QueryEntity queryTax = new QueryEntity();
            Map eqParams = new HashMap();
            String taxTypeIdString = request.getParameter("taxTypeId");
            if (WebUtils.isValidateRealString(taxTypeIdString) && WebUtils.isNumeric(taxTypeIdString)) {
                int taxTypeId = Integer.valueOf(taxTypeIdString);
                eqParams.put("taxTypeByTaxTypeId.id", taxService.queryTaxTypeById(taxTypeId).getId());
            }
            String keyword = request.getParameter("keyword");
            if (WebUtils.isValidateRealString(keyword)) {
                SystemUser systemUser = systemUserService.querySystemUserByUsername(keyword).get(0);
                eqParams.put("systemUserByUserId.id", systemUser.getId());
            } else if (loginSystemUser.getUserRoleByRoleId().getRoleId() == 0) {
                eqParams.put("systemUserByUserId.id", loginSystemUser.getId());
            }
            queryTax.setBeginCreateTime(WebUtils.stringToData(request.getParameter("start_date")));
            queryTax.setEndCreateTime(WebUtils.stringToData(request.getParameter("end_date")));
            queryTax.setDateKeyword("createTime");
            queryTax.setEqParams(eqParams);
            PageModel<Tax> page = new PageModel<>();
            page.setPageSize(5);
            page.setPageNo(Integer.valueOf(pageNoString));
            List<Tax> taxList = taxService.queryTaxPage(queryTax, page);
            JsonArray array = new JsonArray();

            // 读取承办人密钥
            CAConfig caConfig = new CAConfig();
            caConfig.setPK_PASSWORD("123456");
            String cerPath = request.getServletContext().getRealPath("WEB-INF/certificate/");
            String pfxRootPath = handlePath(cerPath) + "root.pfx";
            PrivateKey privateKey = RSAUtils.readPKCS12("D:/pki/root.pfx", caConfig);

            for (Tax tax : taxList) {
                JsonObject list = new JsonObject();
                list.addProperty("id", tax.getId());
                list.addProperty("income", tax.getIncome());
                list.addProperty("tax", tax.getTax());
                list.addProperty("status", tax.getStatus());
                list.addProperty("createTime", WebUtils.timestampToString(tax.getCreateTime()));
                list.addProperty("verifyTime", WebUtils.timestampToString(tax.getVerifyTime()));
                list.addProperty("username", tax.getSystemUserByUserId().getUsername());
                list.addProperty("taxTypeId", tax.getTaxTypeByTaxTypeId().getId());
                list.addProperty("roleId", loginSystemUser.getUserRoleByRoleId().getRoleId());
                //纳税人密钥
                SystemUser systemUser = tax.getSystemUserByUserId();
                PublicKey publicKey = RSAUtils.readCer(systemUser.getPukUrl());
                Packets packets = packetsService.queryPacketsById(tax.getId());
                try {
                    if (packets != null) {
                        // RSA私钥加密后的AES密钥
                        byte[] cipherKeyBytes = BytesHexConverter.HexString2Bytes(packets.getCipherAesKey());
                        // AES密钥
                        byte[] AESKeyBytes = RSAUtils.decryptByRSAPrivateKey(privateKey.getEncoded(), cipherKeyBytes);

                        // 加密文本
                        byte[] cipherTextBytes = BytesHexConverter.HexString2Bytes(packets.getEncryptContent());
                        // 明文文本
                        byte[] plainByte = AESUtil.decrypt(cipherTextBytes, AESKeyBytes);

                        String plainText = new String(plainByte);
                        list.addProperty("content", plainText);

                        if (WebUtils.isValidateRealString(tax.getAttachUrl())) {
                            //加密附件
                            String realAttachUrl = request.getSession().getServletContext().getRealPath(tax.getAttachUrl());
                            byte[] base64FileBytes = BytesIOConverter.fileToBytes(realAttachUrl);
                            byte[] cipherFileBytes = Base64.decode(base64FileBytes);

                            //明文附件
                            byte[] fileBytes = AESUtil.decrypt(cipherFileBytes, AESKeyBytes);
                            String[] realAttachUrlCopyArray = realAttachUrl.split("\\.");
                            String[] attachUrlCopyArray = tax.getAttachUrl().split("\\.");
                            BytesIOConverter.BytesToFile(fileBytes, realAttachUrlCopyArray[0] + "_plain." + realAttachUrlCopyArray[1]);
                            list.addProperty("attachUrl", attachUrlCopyArray[0] + "_plain." + attachUrlCopyArray[1]);
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    list.addProperty("content", "加密数据出错！");
                    list.addProperty("attachUrl","/static/admin/images/error.png");
                    resultJson.addProperty("msg", "加密数据出错！");
                }
                array.add(list);
            }
            JsonObject list = new JsonObject();
            list.add("list", array);
            resultJson.addProperty("status", 200);
            resultJson.addProperty("pages", page.getTotalPageSize());
            resultJson.add("data", list);
        } catch (Exception e) {
            logger.error("AdminTaxController.getTaxList()--error", e);
            resultJson.addProperty("status", 400);
            resultJson.addProperty("msg", "获取列表失败！");
        }
        logger.info(gson.toJson(resultJson));
        return gson.toJson(resultJson);
    }

    @RequestMapping("/getTaxRate")
    @ResponseBody
    public String getTaxRate(HttpServletRequest request) {
        JsonObject resultJson = new JsonObject();
        try {
            int taxTypeId = Integer.valueOf(request.getParameter("taxTypeId"));
            TaxType taxType = taxService.queryTaxTypeById(taxTypeId);
            resultJson.addProperty("taxRate", taxType.getTaxRate());
            resultJson.addProperty("status", 200);
            resultJson.addProperty("msg", "获取税率成功");
        } catch (Exception e) {
            logger.error("AdminTaxController.getTaxRate()--error", e);
            resultJson.addProperty("status", 400);
            resultJson.addProperty("msg", "获取税率失败！");
        }
        logger.info(gson.toJson(resultJson));
        return gson.toJson(resultJson);
    }

    /**
     * 修改税务订单
     */
    @RequestMapping("/updateTax")
    @ResponseBody
    public String updateTax(HttpServletRequest request) {
        try {
            SystemUser loginSystemUser = SingletonLoginUtils.getLoginSystemUser(request);
            if (loginSystemUser.getUserRoleByRoleId().getRoleId() != 0) {
                return getReturnJson(400, "无权修改此纳税人申报内容！", null);
            }
            String taxIdString = request.getParameter("id");
            String incomeString = request.getParameter("income");
            String taxTypeString = request.getParameter("taxTypeId");
            String attachUrl = request.getParameter("attachUrl");
            String content = request.getParameter("content");
            String privateKeyUrl = request.getParameter("privateKeyUrl");
            String privateKeyRealPath = handlePath(request.getServletContext().getRealPath("/")) + privateKeyUrl;
            String password = request.getParameter("password");

            //数据验证
            if (!WebUtils.isValidateRealString(taxIdString, incomeString, taxTypeString, password)
                    || !WebUtils.isNumeric(taxIdString, incomeString, taxTypeString)) {
                return getReturnJson(400, "数据输入不合法！", null);
            }
            Tax tax = taxService.queryTaxById(Integer.valueOf(taxIdString));
            if (tax.getStatus() == (byte) 1) {
                return getReturnJson(400, "已审核，不能再修改！", null);
            }

            String realAttachUrl = null;
            if (WebUtils.isValidateRealString(attachUrl)) {
                realAttachUrl = request.getSession().getServletContext().getRealPath(attachUrl);
            }

            Packets packets = packetsService.packedMessage(tax.getPacketsById(), content, realAttachUrl,
                    privateKeyRealPath, password);
            if (packets == null) return getReturnJson(400, "证书信息错误！", null);
            packetsService.updatePackets(packets);
            //删除私钥
            new File(privateKeyRealPath).delete();

            tax.setIncome(Double.valueOf(incomeString));
            tax.setTaxTypeByTaxTypeId(taxService.queryTaxTypeById(Integer.valueOf(taxTypeString)));
            tax.setAttachUrl(attachUrl.replaceAll("_plain", ""));

            taxService.updateTax(tax);

        } catch (Exception e) {
            logger.error("AdminTaxController.updateTax()--error", e);
            return getReturnJson(400, "更新失败！", null);
        }
        return getReturnJson(200, "更新成功！", "reload");
    }

    @RequestMapping("/updateStatus")
    @ResponseBody
    public String updateStatus(HttpServletRequest request) {
        JsonObject resultJson = new JsonObject();
        try {
            int id = Integer.valueOf(request.getParameter("id"));
            byte status = request.getParameter("status").equals("false") ? (byte) 0 : 1;
            Tax tax = taxService.queryTaxById(id);
            String realAttachUrl = request.getSession().getServletContext().getRealPath(tax.getAttachUrl());
            if (!packetsService.audit(tax, realAttachUrl)) {
                resultJson.addProperty("status", 400);
                resultJson.addProperty("msg", "审核不通过！");
                resultJson.addProperty("url", "reload");
                logger.info(gson.toJson(resultJson));
                return gson.toJson(resultJson);
            }
            tax.setStatus(status);
            tax.setVerifyTime(new Timestamp(System.currentTimeMillis()));
            taxService.updateTax(tax);
            resultJson.addProperty("status", 200);
            resultJson.addProperty("msg", "更新成功");
        } catch (Exception e) {
            logger.error("AdminTaxController.updateStatus()--error", e);
            resultJson.addProperty("status", 400);
            resultJson.addProperty("msg", "审核失败！");
        }
        logger.info(gson.toJson(resultJson));
        return gson.toJson(resultJson);
    }

    /**
     * 初始化税务订单添加页面
     */
    @RequestMapping("/initAddTax")
    public ModelAndView initAddTax() {
        ModelAndView model = new ModelAndView();
        model.addObject("taxTypeList", taxService.queryAllTaxType());
        model.setViewName(addTaxPage);
        return model;
    }

    /**
     * 初始化税务订单列表页面
     *
     * @return
     */
    @RequestMapping("/initTaxList")
    public ModelAndView initTaxList() {
        ModelAndView model = new ModelAndView();
        model.addObject("taxTypeList", taxService.queryAllTaxType());
        model.setViewName(taxListPage);
        return model;
    }


    /**
     * 初始化税务订单列表页面
     *
     * @return 返回
     */
    @RequestMapping("/initManagerTaxList")
    public ModelAndView initManagerTaxList() {
        ModelAndView model = new ModelAndView();
        model.addObject("taxTypeList", taxService.queryAllTaxType());
        model.setViewName(taxManageListPage);
        return model;
    }

    public String handlePath(String source) {
        char[] path = source.toCharArray();
        for (int i = 0; i < path.length; i++) {
            if (path[i] == '\\') {
                path[i] = '/';
            }
        }
        return new String(path);
    }
}
